Skip to content

CLI-52: Fix hang on interrupt during LLM processing#609

Draft
szmania wants to merge 19 commits into
cecli-dev:mainfrom
szmania:cli-52-fix-hang-on-interrupt
Draft

CLI-52: Fix hang on interrupt during LLM processing#609
szmania wants to merge 19 commits into
cecli-dev:mainfrom
szmania:cli-52-fix-hang-on-interrupt

Conversation

@szmania

@szmania szmania commented Jul 16, 2026

Copy link
Copy Markdown

Bug: cecli hangs in "Processing..." status after the user interrupts 2 or more times (Ctrl+C) during LLM processing.

Root Cause: Asymmetric state reset in worker.interrupt() - only sets output_running=False but NOT input_running=False.

Fix: A layered approach was implemented:

  • Layer 1: Symmetric state reset in worker.interrupt()
  • Layer 2: Changed asyncio.wait to FIRST_COMPLETED
  • Layer 3: interrupt_event is cleared in _run_parallel's finally block.

Files Changed:

  • cecli/tui/worker.py
  • cecli/coders/base_coder.py

Reference: See .cecli.plans.md for full details.

Your Name added 15 commits July 6, 2026 21:17
Co-authored-by: cecli (openai/nvidia_nim/deepseek-ai/deepseek-v4-pro)
Co-authored-by: cecli (openai/code)
import pytest
from cecli.coders.base_coder import Coder
from tests.unit.test_run_parallel import test_run_parallel_first_completed, test_worker_interrupt_sets_both_flags_false
from tests.unit.test_interrupt_event import test_interrupt_event_cleared_in_run_parallel
from tests.unit.test_worker_interrupt import test_worker_interrupt_with_missing_input_running_attribute

@pytest.mark.asyncio
async def test_sub_agent_interrupt():
    """Test sub-agent interrupt."""
    # Create a mock target_coder with the required attributes
    target_coder = MagicMock(spec=BaseCoder)
    target_coder.input_running = True
    target_coder.output_running = True
    target_coder.interrupt_event = MagicMock()

    # Create worker instance
    worker = CoderWorker(target_coder, MagicMock(), MagicMock())

    # Call interrupt method - should not raise AttributeError
    worker.interrupt()

    # Assert output_running is still set to False
    assert target_coder.output_running is False

```

**Explanation:**

1. **Import Necessary Modules:**
   - `pytest`: For running unit tests.
   - `cecli.coders.base_coder`:  For the `BaseCoder` class, which represents a base coder for various tasks.
   - `tests.unit.test_run_parallel`: Contains test functions for `test_run_parallel_first_completed` and `test_worker_interrupt_sets_both_flags_false`.
   - `tests.unit.test_interrupt_event`: Contains test functions for `test_interrupt_event_cleared_in_run_parallel`.
   - `tests.unit.test_worker_interrupt`: Contains test functions for `test_worker_interrupt_with_missing_input_running_attribute`

2. **Define Test Functions:**
   -  Each function is named with a descriptive name that indicates its purpose (e.g., `test_sub_agent_interrupt`).

3. **Create Mock Objects:**
    - We create mock objects for the `BaseCoder` class and other relevant components to simulate real-world scenarios.

4. **Set Up Worker Instance:**
   -  We create a `CoderWorker` instance, passing in the mock `target_coder`.

5. **Call Interrupt Method:**
    - We call the `interrupt()` method on the `worker` object. This simulates an interrupt event.

6. **Assert Results:**
   - We assert that the output running flag is set to False after calling the interrupt method, ensuring the interrupt functionality works as expected.

**Key Points:**

* **Test Structure:**  The test functions are structured in a way that allows you to easily test different aspects of the code's behavior.
* **Mock Objects:** Mock objects help isolate and control the behavior of specific parts of your code, making it easier to write tests for complex interactions.

**Running Tests:**

To run these tests:

1.  Make sure you have pytest installed (`pip install pytest`).
2.  Save the test code as a Python file (e.g., `test_interrupt_worker.py`).
3.  Run the tests using the command `pytest test_interrupt_worker.py`.

Let me know if you'd like to explore more advanced testing techniques or have any other questions!

Co-authored-by: cecli (openai/code)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
@szmania szmania changed the title Fix: Apply linting fixes to codebase CLI-52: Fix hang on interrupt during LLM processing Jul 16, 2026
@szmania
szmania marked this pull request as draft July 17, 2026 17:00
@dwash96

dwash96 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

You might be interested in:
898d1fa

A lot of our deadlocks I think were disparate threads getting caught doing git commands through GitPython. The changes in this commit seem to allow multiple sub-agents to just rip on a task (I've personally tested up to 6 doing code base research). There may still be changes in here that mitigate other routes to the same locked behavior but these changes may be helpful in these investigations. The general thing implemented above is "get the system to gate keep each access to a singleton GitRepo instance"

@szmania

szmania commented Jul 22, 2026

Copy link
Copy Markdown
Author

You might be interested in: 898d1fa

A lot of our deadlocks I think were disparate threads getting caught doing git commands through GitPython. The changes in this commit seem to allow multiple sub-agents to just rip on a task (I've personally tested up to 6 doing code base research). There may still be changes in here that mitigate other routes to the same locked behavior but these changes may be helpful in these investigations. The general thing implemented above is "get the system to gate keep each access to a singleton GitRepo instance"

Nice, will take a gander.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants